#pragma once
#include <stdio.h>
#include <signal.h>
#include <atomic>
#include <string>
#include <thread>
#include <iostream>
#include <vector>
#include <mutex>
#include <queue>
#include <opencv2/opencv.hpp>

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <libavutil/timestamp.h>
// #include <libswscale/swscale.h>

#include <rk_mpi.h>
#include <mpp_frame.h>
#include <rk_mpi_cmd.h>

#include <rk_venc_cmd.h> 
#include <mpp_packet.h> 
#include <rk_venc_ref.h> 
#include <rk_mpi.h> 
#include <mpi_enc_utils.h> 
#include <mpp_buffer.h>
#include <mpi_dec_utils.h>

#include <mpp_env.h> 
#include <mpp_meta.h> 
#include <mpp_common.h> 
#include <mpp_mem.h> 

}

// #include "osd/osd_base.h"
#include "base_util/utils.h"
#include "base_util/log_lite.h"
#include "total_struct.h"

#define STREAM_FRAME_SIZE 2097152

namespace stream {

typedef struct {
        uint8_t *data;
        uint32_t size;
} SpsHeader;

typedef struct MpiEnc {
	// global flow control flag
    RK_U32 frm_eos;
    RK_U32 pkt_eos;
    RK_U32 frm_pkt_cnt;
    RK_S32 frame_count;
    RK_U64 stream_size;

	// src and dst
	//    FILE *fp_input;
	//    FILE *fp_output;

	// base flow context
    MppCtx ctx;
    MppApi *mpi;
    RK_S32 chn;

    MppEncCfg cfg;
    MppEncPrepCfg prep_cfg;
    MppEncRcCfg rc_cfg;
    MppEncCodecCfg codec_cfg;
    MppEncSliceSplit split_cfg;
    MppEncOSDPltCfg osd_plt_cfg;
    MppEncOSDPlt    osd_plt;
    MppEncOSDData   osd_data;
    MppEncROIRegion roi_region[3];
    MppEncROICfg    roi_cfg;

    // input / output
    MppBufferGroup buf_grp;
    MppBuffer frm_buf;
    MppBuffer pkt_buf;
    MppEncSeiMode sei_mode;
    MppEncHeaderMode header_mode;

    // paramter for resource malloc
    RK_U32 width;
    RK_U32 height;
    RK_U32 hor_stride;
    RK_U32 ver_stride;
    MppFrameFormat fmt;
    MppCodingType type;
    RK_S32 num_frames;
    RK_S32 loop_times;
    // CamSource *cam_ctx;

    // resources
    size_t header_size;
    size_t frame_size;
    /* NOTE: packet buffer may overflow */
    size_t packet_size;

    RK_U32 osd_enable;
    RK_U32 osd_mode;
    RK_U32 split_mode;
    RK_U32 split_arg;

    RK_U32 user_data_enable;
    RK_U32 roi_enable;

      /* -qc */
    RK_S32              qp_init;
    RK_S32              qp_min;
    RK_S32              qp_max;
    RK_S32              qp_min_i;
    RK_S32              qp_max_i;

    // rate control runtime parameter

    RK_S32 fps_in_flex;
    RK_S32 fps_in_den;
    RK_S32 fps_in_num;
    RK_S32 fps_out_flex;
    RK_S32 fps_out_den;
    RK_S32 fps_out_num;
    RK_S32 bps;
    RK_S32 bps_max;
    RK_S32 bps_min;
    RK_S32 rc_mode;
    RK_S32 gop_mode;
    RK_S32 gop_len;
    RK_S32 vi_len;
} MpiEncData;

typedef struct MpiEncArgs_t {
    char                *file_input;
    char                *file_output;
    char                *file_cfg;
    // dictionary          *cfg_ini;

    MppCodingType       type;
    MppFrameFormat      format;
    RK_S32              num_frames;
    RK_S32              loop_cnt;

    RK_S32              width;
    RK_S32              height;
    RK_S32              hor_stride;
    RK_S32              ver_stride;

    RK_S32              bps_target;
    RK_S32              bps_max;
    RK_S32              bps_min;
    RK_S32              rc_mode;

    RK_S32              fps_in_flex;
    RK_S32              fps_in_num;
    RK_S32              fps_in_den;
    RK_S32              fps_out_flex;
    RK_S32              fps_out_num;
    RK_S32              fps_out_den;

    RK_S32              qp_init;
    
    RK_S32              gop_mode;
    RK_S32              gop_len;
    RK_S32              vi_len;

    MppEncHeaderMode    header_mode;

    MppEncSliceSplit    split;
} MpiEncArgs;


};